/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bungabungaball.gamestates;

import bungabungaball.GlobalSettings;
import bungabungaball.PlayerControl;
import bungabungaball.gamestates.menu.Menu;
import bungabungaball.gamestates.menu.MenuEntry;
import bungabungaball.player.Network;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.gui.TextField;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

/**
 * A game state to enter a network game hosted on a different pc
 *
 * @author Ingo Klose, Stephan Meyer, Sebastian Lehmann
 * @version 1.0
 */
public class JoinNetworkGame extends BasicGameState implements Menu {

    /**
     * *
     * the id of the game state
     */
    private int stateID = -1;
    /**
     * a text field to enter the IP adress
     */
    private TextField textField;
    /**
     * *
     * Has the server sent that he is ready for a match
     */
    private boolean startGameOkForServer;
    /**
     * Has the client clicked that he is read for a match
     */
    private boolean startGameOkForClient;
    /**
     * a final menu entry to start the game
     */
    private MenuEntry startGame;
    /**
     * is the connection created correctry
     */
    private boolean clientCorrectlyCreated;
    /**
     * An image of the driver
     */
    private Image driver;
    /**
     * An image of the driver
     */
    private Image driver2;
    /**
     * Bunga Logo
     */
    private Image bunga;
    /**
     * Bunga Logo
     */
    private Image bungamenu;
    /**
     * x Position of the driver
     */
    private double driverX;
    /**
     * Y Position of the driver
     */
    private double driverY;
    /**
     * A counter for the driver
     */
    private double counter = 0;
    /**
     * A checker for the driver
     */
    private boolean checker = true;

    /**
     * Contructor
     *
     * @param stateID
     */
    public JoinNetworkGame(int stateID) {
        this.stateID = stateID;
        driverX = 600;
        driverY = 350;
    }

    /**
     * Get the id of the state
     *
     * @return id of the state
     */
    @Override
    public int getID() {
        return stateID;
    }

    /**
     * Init, create all objects
     *
     * @param gc
     * @param sbg
     * @throws SlickException
     */
    @Override
    public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
        textField = new TextField(gc, gc.getDefaultFont(), 200, 150, 300, 20);
        textField.setFocus(true);
        startGame = new MenuEntry("Spiel starten", 100, 500, gc.getDefaultFont());
        textField.setText("");
        driver = new Image("\\img\\player1.png");

        driver2 = new Image("\\img\\player2.png");
        driver2.setRotation(45);

        bunga = new Image("\\img\\bungabunga.png");

    }

    /**
     *
     * @param gc
     * @param sbg
     * @throws SlickException set all to default on entering the state
     */
    @Override
    public void enter(GameContainer gc, StateBasedGame sbg) throws SlickException {
        startGameOkForServer = false;
        startGameOkForServer = false;
        clientCorrectlyCreated = false;

        PlayerControl.client = new Client(10000, 10000);
        PlayerControl.client.start();
    }

    /**
     * rendet the state
     *
     * @param gc
     * @param sbg
     * @param g
     * @throws SlickException
     */
    @Override
    public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
        g.setColor(Color.red);
        g.setFont(MainMenu.font);
        g.drawString("Server finden", 100, 100);

        g.setColor(Color.white);
        g.drawString("IP-Adresse:", 100, 150);


        textField.setFocus(true);
        textField.setBorderColor(new Color(0, 0, 0));
        textField.setBackgroundColor(new Color(255, 255, 255));
        textField.setTextColor(new Color(0, 0, 0));
        textField.render(gc, g);

        if (clientCorrectlyCreated) {
            Input input = gc.getInput();
            int mouseX = input.getAbsoluteMouseX();
            int mouseY = input.getAbsoluteMouseY();
            g.setColor(startGame.checkMouseIn(mouseX, mouseY) ? Color.green : Color.white);
            g.drawString(startGame.text, startGame.x, startGame.y);

            g.setColor(Color.white);
            g.drawString("Selber bereit: " + (startGameOkForClient ? "Ja" : "Nein"), 100, 220);
            g.drawString("Gegner bereit: " + (startGameOkForServer ? "Ja" : "Nein"), 100, 240);
        }

        g.drawImage(driver, (int) driverX, (int) driverY);

        g.drawImage(driver2, 500, 100);


        g.drawImage(bunga, 400, 0);

    }

    /**
     * handle all input
     *
     * @param gc
     * @param sbg
     * @param delta
     * @throws SlickException
     */
    @Override
    public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
        Input input = gc.getInput();

        int mouseX = input.getAbsoluteMouseX();
        int mouseY = input.getAbsoluteMouseY();

        if (input.isKeyDown(Input.KEY_ESCAPE)) {
            try {
                Thread.sleep(250);
            } catch (InterruptedException ex) {
                Logger.getLogger(GamePlay.class.getName()).log(Level.SEVERE, null, ex);
            }
            sbg.enterState(bungabungaball.BungaBungaBall.MAINMENUSTATE);
        }
        if (input.isKeyDown(Input.KEY_RETURN)) {
            String regExIP = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";
            String regExHost = "^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\\-]*[A-Za-z0-9])$";
            if (textField.getText().matches(regExIP) || textField.getText().matches(regExHost)) {
                System.out.println("Gültige IP/Hoste eingegeben");
                Network.setServerIp(textField.getText());
                GlobalSettings.currentGameMode = GlobalSettings.gameModes.Client;

                // Connect to the server
                try {
                    PlayerControl.client.connect(5000, textField.getText(), 54555, 54777);
                    Kryo kryo = PlayerControl.client.getKryo();
                    for (Class cl : GlobalSettings.kryoRegisterClassNames) {
                        kryo.register(cl);
                    }

                    PlayerControl.client.addListener(new Listener() {
                        @Override
                        public void received(Connection connection, Object object) {
                            if (object instanceof Boolean) {
                                Boolean response = (Boolean) object;
                                if (response) {
                                    startGameOkForServer = true;
                                    PlayerControl.client.removeListener(this);
                                }
                            }
                        }
                    });
                    clientCorrectlyCreated = true;
                } catch (IOException ex) {
                    //Logger.getLogger(JoinNetworkGame.class.getName()).log(Level.SEVERE, null, ex);
                    System.out.println("Es konnte keine Verbindung zum Server hergestellt werden.");
                    System.out.println(ex.toString());
                }


                //sbg.enterState(bungabungaball.BungaBungaBall.GAMEPLAYSTATESingle);
            } else {
                /**
                 * @TODO: Richtige Fehlermeldung ausgeben
                 */
                System.out.println("UNGÜLTIGE IP/Hoste eingegeben");
            }
        }


        if (input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON)) {
            if (startGame.checkMouseIn(mouseX, mouseY)) {
                PlayerControl.client.sendTCP(new Boolean(true));
                startGameOkForClient = true;
            }
        }


        // Check if start Game:
        if (startGameOkForServer && startGameOkForClient) {
            GlobalSettings.currentGameMode = GlobalSettings.gameModes.Client;
            sbg.enterState(bungabungaball.BungaBungaBall.GAMEPLAYSTATESingle);
        }

        this.drive();
        this.drive();
    }

    /**
     * Updates the driver Image
     */
    public void drive() {
        //x = 600 y = 400
        double speedRotation = Math.toRadians(driver.getRotation() - 90.f);

        driverX = driverX + 2 * Math.cos(speedRotation);
        driverY = driverY + 2 * Math.sin(speedRotation);

        if (checker && counter <= 270) {
            driver.rotate(1);
        } else if (!checker && counter <= 270) {
            driver.rotate(-1);
        }
        counter++;
        if (counter == 385) {
            counter = 0;
            if (checker) {
                checker = false;
            } else {
                checker = true;
            }
        }
    }
}
